package com.github.util;

import com.github.MavenBean;
import com.github.MavenVersion;
import com.github.UiApplication;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.github.drinkjava2.jsqlbox.JSQLBOX.nExecute;
import static com.github.drinkjava2.jsqlbox.JSQLBOX.nQueryForIntValue;

public class HttpUtil {

    public static List<MavenBean> getSearchList(String name) throws IOException {
        List<MavenBean> rs = new ArrayList<MavenBean>();
        Document doc = null;
        try {
            doc = Jsoup.connect("https://mvnrepository.com/search").data("q", name).timeout(5000).header("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3").get();
        } catch (IOException e) {
            UiApplication.log.append(e.getMessage() + "\r\n");
            return null;
        }
        Elements es = doc.select("div.im");
        for (Element e : es
        ) {
            Element te = e.selectFirst("div.im-header .im-title");
            Element ste = e.selectFirst("div.im-header .im-subtitle");
            if (te != null) {
                MavenBean bean = new MavenBean();
                Elements ea = te.select("a");
                Elements sea = ste.select("a");
                String title = ea.get(0).html();
                String url = ea.get(0).attr("href");
                bean.setUrl("https://mvnrepository.com" + url);
                bean.setName(title);
                String useage = ea.get(1).select("b").html().replace(",", "");
                bean.setUseage(useage);
                String groupId = sea.get(0).html();
                bean.setGroupId(groupId);
                String artifactId = sea.get(1).html();
                bean.setArtifactId(artifactId);
                rs.add(bean);
            }
        }
        return rs;
    }

    public static List<MavenVersion> getVersions(String url) throws IOException {
        List<MavenVersion> versionList = new ArrayList<MavenVersion>();
        Document doc = null;
        try {
            doc = Jsoup.connect(url).get();
        } catch (IOException e) {
            UiApplication.log.append(e.getMessage() + "\r\n");
            return null;
        }
        Elements es = doc.select("div.gridcontainer table tbody tr");
        for (Element e : es
        ) {
            MavenVersion v = new MavenVersion();
            Elements nes = e.select("td");
            if (nes.size() > 4) {
                v.setRelease(nes.get(1).selectFirst("a").html());
                v.setUseage(nes.get(3).selectFirst("a") == null ? "0" : nes.get(3).selectFirst("a").html());
                v.setDate(nes.get(4).html());
            } else {
                v.setRelease(nes.get(0).selectFirst("a").html());
                v.setUseage(nes.get(2).selectFirst("a") == null ? "0" : nes.get(2).selectFirst("a").html());
                v.setDate(nes.get(3).html());
            }
            v.setUrl(url + "/" + v.getRelease());
            versionList.add(v);
        }
        return versionList;
    }

    /**
     * 从网络Url中下载文件
     *
     * @param urlStr
     * @param fileName
     * @param savePath
     * @throws IOException
     */
    private static void downLoadFromUrl(String urlStr, String fileName, String savePath) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //设置超时间为3秒
        conn.setConnectTimeout(3 * 1000);
        //防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

        //得到输入流
        InputStream inputStream = conn.getInputStream();
        //获取自己数组
        byte[] getData = readInputStream(inputStream);
        //文件保存位置
        File saveDir = new File(savePath);
        if (!saveDir.exists()) {
            saveDir.mkdir();
        }
        File file = new File(saveDir + File.separator + fileName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(getData);
        if (fos != null) {
            fos.close();
        }
        if (inputStream != null) {
            inputStream.close();
        }
        UiApplication.log.append(fileName + " 下载成功\r\n");
        UiApplication.log.setSelectionStart(UiApplication.log.getText().length());
        // System.out.println("info:" + url + " download success");
    }

    /**
     * 从输入流中获取字节数组
     *
     * @param inputStream
     * @return
     * @throws IOException
     */
    private static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    public static void downloadByVersion(String url, String[] dirs, String BaseRoot,String af,String gr,String ve) throws IOException {
        Document doc = null;
        try {
            doc = Jsoup.connect(url).get();
        } catch (IOException e) {
            UiApplication.log.append(e.getMessage() + "\r\n");
            return;
        }
        Elements es = doc.select("table.grid tbody tr");
        for (Element e : es
        ) {
            url = "";
            String th = e.select("th").html();
            if (th.equals("Files")) {
                Elements as = e.select("a");
                for (Element a : as
                ) {
                    if (a.html().equals("View All"))
                        url = a.attr("href");
                }
                break;
            }
        }
        Element es2 = doc.selectFirst("div.version-section div.gridcontainer");
        Elements trs = es2.select("tbody tr");
        for (Element tr : trs
        ) {
            String artifactId=tr.select("td:nth-child(3) a:nth-child(1)").html();
            String[] artifactIds = artifactId.split("\\.");
            String[] dir = new String[artifactIds.length + 2];
            String groupId = tr.select("td:nth-child(3) a:nth-child(2)").html();
            for (int j = 0; j < artifactIds.length; j++) {
                dir[j] = artifactIds[j];
            }
            dir[dir.length - 2] = groupId;
            String version=tr.select("td:nth-child(4) a").html();;
            dir[dir.length - 1] = version;
            String url_ = "https://mvnrepository.com" + tr.select("td:nth-child(4) a").attr("href");
            UiApplication.log.append("下载依赖" + groupId + "\r\n");
            UiApplication.log.setSelectionStart(UiApplication.log.getText().length());
            int i = nQueryForIntValue("select count(1) from downloadHistory where artifactId=? and groupId=? and version=? and state=2",
                    groupId,artifactId, version);
            if(i>0&&!UiApplication.isAutoDo){
                UiApplication.log.append("本地已存在=》"+artifactId+">"+groupId+">"+version+"\r\n");
                UiApplication.log.setSelectionStart(UiApplication.log.getText().length());
                continue;
            }
            downloadByVersion(url_, dir, BaseRoot,groupId,artifactId,version);
        }
        if (url.equals("")) return;
        try {
            doc = Jsoup.connect(url).get();
        } catch (IOException e) {
            UiApplication.log.append(e.getMessage() + "\r\n");
            return;
        }
        Elements as = doc.select("a");
        String id=System.currentTimeMillis()+"";
        if (UiApplication.iszjcj)
            nExecute("insert into downloadHistory(id,artifactId,groupId,version,state,createTime) values (?,?,?,?,?,?)",
                    id,af,gr,ve,1,new Date());
        for (Element a : as
        ) {
            if (a.html().indexOf("../") != -1)
                continue;
            String tempRoot = "";
            if (UiApplication.iszjcj) {
                File root = createMultilevelDirectory(dirs, BaseRoot);
                tempRoot = root.getAbsolutePath();
            } else {
                String name = a.html();
                if (name.indexOf(".jar") == name.length() - 4 &&
                        name.indexOf("sources") == -1 && name.indexOf("javadoc") == -1
                &&name.indexOf("test")==-1)
                    tempRoot = BaseRoot;
                else
                    continue;
            }
            downLoadFromUrl(url + "/" + a.attr("href"), a.html(), tempRoot);
        }
        if (UiApplication.iszjcj)
            nExecute("update downloadHistory set state=2, finshTime=? where id=?",new Date(),id);
    }

    private static File createMultilevelDirectory(String[] directories, String rootPath) {
        if (directories.length == 0) {
            return null;
        }
        File root = new File(rootPath);
        for (int i = 0; i < directories.length; i++) {

            File directory = new File(root, directories[i]);
            if (!directory.exists())
                directory.mkdir();
            root = directory;
        }
        return root;
    }
}
